package com.sunlands.zlcx.usercenter.controller;

import com.sunlands.zlcx.usercenter.common.annotation.AuthSig;
import com.sunlands.zlcx.usercenter.common.annotation.AutoLog;
import com.sunlands.zlcx.usercenter.constant.BuryingPointOperationType;
import com.sunlands.zlcx.usercenter.constant.YN;
import com.sunlands.zlcx.usercenter.constant.dic.ADVERT;
import com.sunlands.zlcx.usercenter.constant.dic.POSTGRADUATE_ALERT_ADVERT;
import com.sunlands.zlcx.usercenter.domain.BuryingPointDO;
import com.sunlands.zlcx.usercenter.domain.DicDO;
import com.sunlands.zlcx.usercenter.domain.UsersExtInfoDO;
import com.sunlands.zlcx.usercenter.exception.GlobalExceptionHandler;
import com.sunlands.zlcx.usercenter.service.BuryingPointServiceImpl;
import com.sunlands.zlcx.usercenter.service.DicServiceImpl;
import com.sunlands.zlcx.usercenter.service.UserCardsServiceImpl;
import com.sunlands.zlcx.usercenter.service.UsersServiceImpl;
import com.sunlands.zlcx.usercenter.util.BeanPropertiesUtil;
import com.sunlands.zlcx.usercenter.vo.AdvertVO;
import com.sunlands.zlcx.usercenter.vo.UsersVO;
import com.sunlands.zlcx.usercenter.vo.response.BusinessResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

import static com.sunlands.zlcx.usercenter.constant.dic.POSTGRADUATE_ALERT_ADVERT.*;

/**
 * @author anjl
 * @date 1:35 PM 2019/4/15
 * description:
 */
@SuppressWarnings("unused")
@Api(tags = "21、广告API", position = 1)
@ApiResponses(value = {@ApiResponse(code = 400, response = GlobalExceptionHandler.class, message = "数据校验失败"), @ApiResponse(code = 500, response = GlobalExceptionHandler.class, message = "内部错误")})
@Slf4j
@RestController
@RequestMapping("/advert")
public class AdvertController implements AuthSupport, BeanPropertiesUtil {

    @AutoLog
    @ApiOperation(value = "考研自习室-广告提示", notes = "考研自习室-广告提示")
    @PostMapping("/alert/tips")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    public BusinessResult<AdvertVO> advertTips() {
        Long userId = currentUserId();

        //广告关闭，不再展示
        DicDO dic = dicService.findByCode(POSTGRADUATE_ALERT_ADVERT.dicName());
        if (YN.NO.getCode().equals(dic.filter(open.name()).getCode())) {
            return BusinessResult.createSuccessInstance(null);
        }

        //用户已经上报名片，不再展示
        Boolean exist = userCardsService.existsByUserId(userId);
        if (exist) {
            return BusinessResult.createSuccessInstance(null);
        }
        UsersVO users = usersService.find(userId);
        if (Objects.nonNull(users)
                && Objects.nonNull(users.getPhone())
                && userCardsService.existsByCard(users.getPhone())) {
            return BusinessResult.createSuccessInstance(null);
        }

        //弹窗次数
        UsersExtInfoDO extInfo = usersService.findExtInfoByUserId(userId);
        Integer advertFrequencyTimes = 0;
        if (Objects.nonNull(extInfo) && Objects.nonNull(extInfo.getPostGraduateAdvertFrequencyTimes())) {
            advertFrequencyTimes = extInfo.getPostGraduateAdvertFrequencyTimes();
        }

        Long times = dic.filter(POSTGRADUATE_ALERT_ADVERT.times.name()).getCode();
        //检查弹窗次数，超过次数不再展示
        if (advertFrequencyTimes >= times) {
            return BusinessResult.createSuccessInstance(null);
        }

        //展示弹窗内容
        AdvertVO advert = AdvertVO
                .builder()
                .h5_url(dic.filter(h5_url.name()).getData())
                .type(dic.filter(type.name()).getData())
                .build();

        //单个用户单独记录，减少复杂度，不考虑并发
        extInfo.setPostGraduateAdvertFrequencyTimes(advertFrequencyTimes + 1);
        usersService.saveExtInfo(extInfo);

        //埋点记录
        buringPoint(userId);
        return BusinessResult.createSuccessInstance(advert);

    }

    private void buringPoint(Long userId) {

        commonTaskExecutor.submit(() -> {
            DicDO dic = dicService.findByCode(POSTGRADUATE_ALERT_ADVERT.dicName());
            BuryingPointDO buryingPoint = BuryingPointDO
                    .builder()
                    .userId(userId)
                    .modular(ADVERT.dicName().toLowerCase())
                    .function(dic.filter(type.name()).getData())
                    .pointSite("alert")
                    .operationType(BuryingPointOperationType.show.name())
                    .build();
            buryingPointService.add(buryingPoint);
        });
    }

    @Autowired
    @Lazy
    private UsersServiceImpl usersService;
    @Autowired
    private UserCardsServiceImpl userCardsService;
    @Autowired
    private DicServiceImpl dicService;
    @Resource(name = "commonTaskExecutor")
    private AsyncTaskExecutor commonTaskExecutor;
    @Autowired
    private BuryingPointServiceImpl buryingPointService;
}
